package io.adrainty.bolee.insurance.handler.impl;

import io.adrainty.bolee.framework.commons.basic.ResponseCode;
import io.adrainty.bolee.framework.commons.exception.AppException;
import io.adrainty.bolee.insurance.constants.InsuranceConstant;
import io.adrainty.bolee.insurance.models.aggregate.InsuranceProcessDTO;
import io.adrainty.bolee.insurance.models.entity.CustomerRelationEntity;
import io.adrainty.bolee.insurance.models.entity.InsuranceCoefficientEntity;
import io.adrainty.bolee.insurance.models.entity.InsuranceEntity;
import io.adrainty.bolee.insurance.models.entity.InsurancePlanEntity;
import io.adrainty.bolee.insurance.models.request.DoInsuranceDTO;
import io.adrainty.bolee.insurance.models.valobj.CheckRuleEnum;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.List;

/**
 * 旅游险（团险实现）
 *
 * @author AdRainty
 * @version V1.0.0
 * @since 2025/8/24 下午11:52
 */

@Component
public class TravelInsuranceHandler extends SafeguardInsuranceHandler {

    @Override
    public String doPremium(DoInsuranceDTO doInsureVo) {
        InsuranceProcessDTO insuranceProcessDTO = buildInsureProcessDTO(doInsureVo.getInsuranceId(), doInsureVo.getInsurancePlanId(),
                doInsureVo.getCompanyNo(), doInsureVo.getInsuranceCoefficentIds());
        InsuranceEntity insuranceEntity = insuranceProcessDTO.getInsuranceEntity();
        InsurancePlanEntity insurancePlanEntity = insuranceProcessDTO.getInsurancePlanEntity();
        List<InsuranceCoefficientEntity> insuranceCoefficientList = insuranceProcessDTO.getInsuranceCoefficientList();
        List<CustomerRelationEntity> customerRelationEntities = buildCustomerRelationList(doInsureVo.getCustomerRelationIds());

        checkBaseOnly(insuranceCoefficientList);
        checkRequireCoefficient(insuranceCoefficientList, InsuranceConstant.TRAVEL_CHECK_RULE);

        insuranceCoefficientList = numberOfPeopleHandler(insuranceCoefficientList,
                insuranceEntity.getId(), customerRelationEntities);
        return premiumComputeTravel(insurancePlanEntity, insuranceCoefficientList);
    }

    /**
     * 旅游险(团险)保费计算
     *
     * @param insurancePlanEntity      保险计划
     * @param insuranceCoefficientList 保险系数项
     * @return 保费
     */
    protected String premiumComputeTravel(InsurancePlanEntity insurancePlanEntity, List<InsuranceCoefficientEntity> insuranceCoefficientList) {
        // 最终系数合=累加所有系数维度值[不包含投保人数系数]+1
        BigDecimal sumScore = insuranceCoefficientList.stream()
                .filter(coefficient -> !InsuranceConstant.NUMBER_OF_PEOPLE.equals(coefficient.getCoefficientKey()))
                .map(n -> ObjectUtils.defaultIfNull(n.getScore(), BigDecimal.ZERO))
                .reduce(BigDecimal.ZERO, BigDecimal::add).add(BigDecimal.ONE);
        // 投保人数系数
        InsuranceCoefficientEntity numberOfPeople = insuranceCoefficientList.stream()
                .filter(n -> InsuranceConstant.NUMBER_OF_PEOPLE.equals(n.getCoefficientKey()))
                .findFirst().orElseThrow(() -> new AppException(ResponseCode.INSURANCE_CALCULATE_ERROR, "请选择投保人数"));
        BigDecimal numberOfPeopleScore = numberOfPeople.getScore();
        DecimalFormat decimalFormat = new DecimalFormat("0.00");
        return decimalFormat.format(insurancePlanEntity.getPrice().multiply(sumScore).multiply(numberOfPeopleScore));
    }

    @Override
    public CheckRuleEnum supportCheckRule() {
        return CheckRuleEnum.TRAVEL;
    }

}
